package amis

import (
	"fiberAmisAdmin/config"
	db "fiberAmisAdmin/config"
	"fmt"
	"reflect"
	"strconv"
)

// QueryData 查询数据库数据
func QueryData(fields []map[string]interface{}, tableName string, pageStr string, pageSizeStr string, conditions, params interface{}) ([]map[string]interface{}, int, error) {
	// 获取数据库表的字段列表
	var columns []struct {
		Field string `gorm:"column:Field"`
	}
	err := db.MySQLDB.Raw("SHOW COLUMNS FROM " + tableName).Scan(&columns).Error
	if err != nil {
		return nil, 0, fmt.Errorf("failed to get table columns: %v", err)
	}

	// 创建一个字段存在性检查的集合
	existingFieldSet := make(map[string]struct{}, len(columns))
	for _, column := range columns {
		existingFieldSet[column.Field] = struct{}{}
	}

	// 过滤字段，确保 fieldNames 只包含数据库中存在的字段
	fieldNames := make([]string, 0, len(fields))
	for _, field := range fields {
		fieldName := field["name"].(string)
		if _, exists := existingFieldSet[fieldName]; exists {
			fieldNames = append(fieldNames, fieldName)
		}
	}

	var result []map[string]interface{}
	var totalCount int64

	page, err := strconv.Atoi(pageStr)
	if err != nil || page < 1 {
		return nil, 0, fmt.Errorf("invalid page number: %v", err)
	}

	pageSize, err := strconv.Atoi(pageSizeStr)
	if err != nil || pageSize < 1 {
		return nil, 0, fmt.Errorf("invalid page size: %v", err)
	}
	offset := (page - 1) * pageSize

	// 创建查询链，首先获取总条数
	query := db.MySQLDB.Table(tableName).Select(fieldNames)
	if conditions != "" {
		query = query.Where(conditions, params)
	}
	err = query.Count(&totalCount).Error
	if err != nil {
		return nil, 0, err
	}

	// 执行分页查询
	err = query.Offset(offset).Limit(pageSize).Find(&result).Error
	if err != nil {
		return nil, 0, err
	}

	return result, int(totalCount), nil
}

/**
* @Description: 生成表单字段
* @param: fields []map[string]interface{} 字段配置
* @param:fieldsForm []map[string]interface{} 表单字段配置
* @return: []map[string]interface{} 表单字段配置
 */
func TableColumn(fields []map[string]interface{}, fieldsForm []map[string]interface{}, fieldsDetail []map[string]interface{}, route string, attribute map[string]interface{}, button map[string]bool, conditions, params, adminServer interface{}) (map[string]interface{}, error) {
	// 提取配置参数
	tableName := attribute["tableName"].(string)
	page := attribute["page"].(string)
	pageSize := attribute["pageSize"].(string)
	// 构建列配置
	columns := generateControlFields(fields)
	// 查询数据库
	result, totalCount, err := QueryData(fields, tableName, page, pageSize, conditions, params)
	if err != nil {
		return nil, err
	}
	// 添加操作列
	operationColumn := map[string]interface{}{
		"type":    "operation",
		"label":   "操作",
		"buttons": buildButtons(fieldsForm, fieldsDetail, button, route),
	}
	columns = append(columns, operationColumn)

	// 使用封装的判断方法
	rows := CallMethodIfExists(adminServer, "ListToRows", result)
	// 创建返回的数据结构
	data := map[string]interface{}{
		"columns": columns,
		"count":   totalCount,
		"rows":    rows,
	}
	return data, nil
}

/**
* @Description: 根据实例和方法名调用对应方法（如果存在）
* @param: instance interface{} 要调用方法的实例
* @param: methodName string 方法名
* @param: args ...interface{} 调用方法时传入的参数
* @return: interface{} 调用方法的返回值，如果方法不存在则返回第一个参数
 */
func CallMethodIfExists(instance interface{}, methodName string, args ...interface{}) interface{} {
	instanceValue := reflect.ValueOf(instance)
	method := instanceValue.MethodByName(methodName)
	if method.IsValid() && method.Kind() == reflect.Func {
		// 构造反射值切片，用于传递给调用的函数
		in := make([]reflect.Value, len(args))
		for i, arg := range args {
			in[i] = reflect.ValueOf(arg)
		}
		// 调用目标方法并返回其结果
		methodResult := method.Call(in)
		if len(methodResult) > 0 {
			return methodResult[0].Interface()
		}
	}
	return args[0] // 如果方法不存在，返回第一个参数 result
}

// 构建操作按钮
func buildButtons(fieldsForm []map[string]interface{}, fieldsDetail []map[string]interface{}, button map[string]bool, route string) []map[string]interface{} {
	buttons := []map[string]interface{}{}
	// 编辑按钮
	if button["showEditButton"] {
		buttons = append(buttons, buildButtonEdit("修改", "dialog", "修改表单", fieldsForm, route))
	}
	// 查看详情按钮
	if button["showDetailButton"] {
		buttons = append(buttons, buildButtonDetail("详情", "dialog", "查看详情", fieldsDetail))
	}
	// 删除按钮
	if button["showDeleteButton"] {
		buttons = append(buttons, buildDeleteButton(route))
	}

	return buttons
}

// 构建编辑按钮
func buildButtonEdit(label, actionType, title string, fields []map[string]interface{}, route string) map[string]interface{} {
	return map[string]interface{}{
		"label":      label,
		"type":       "button",
		"level":      "link",
		"actionType": actionType,
		actionType: map[string]interface{}{
			"title": title,
			"body": map[string]interface{}{
				"type": "form",
				"api": map[string]interface{}{
					"method": "put",
					"url":    config.GetServerConfigValue("app_url") + route + "/${id}",
				},
				"controls": generateControlFields(fields),
			},
		},
	}
}

// 构建查看详情按钮
func buildButtonDetail(label, actionType, title string, fields []map[string]interface{}) map[string]interface{} {
	return map[string]interface{}{
		"label":      label,
		"type":       "button",
		"level":      "link",
		"actionType": actionType,
		actionType: map[string]interface{}{
			"title": title,
			"body": map[string]interface{}{
				"type":     "form",
				"controls": generateControlFields(fields),
			},
		},
	}
}

// 构建删除按钮
func buildDeleteButton(route string) map[string]interface{} {
	return map[string]interface{}{
		"label":       "删除",
		"type":        "button",
		"actionType":  "ajax",
		"level":       "link",
		"className":   "text-danger",
		"disabledOn":  "this.username === 'admin'",
		"confirmText": "确认要删除？",
		"api": map[string]interface{}{
			"method": "delete",
			"url":    config.GetServerConfigValue("app_url") + route + "/${id}",
		},
	}
}
